package com.cxx.purchasecharge.dal.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.cxx.purchasecharge.core.model.persistence.Authority;
import com.cxx.purchasecharge.core.model.persistence.Resource;
import com.cxx.purchasecharge.core.model.persistence.Role;
import com.cxx.purchasecharge.core.model.persistence.User;
import com.cxx.purchasecharge.dal.AuthorityDao;
import com.cxx.purchasecharge.dal.ResourceDao;
import com.cxx.purchasecharge.dal.RoleDao;
import com.cxx.purchasecharge.dal.UserDao;
import com.cxx.purchasecharge.dal.UserDataInitializer;

@Repository ("userDataDBInitializer")
public class UserDataDBInitializer implements UserDataInitializer
{
    private static final Logger logger = Logger.getLogger (UserDataDBInitializer.class);

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private AuthorityDao authorityDao;
    @Autowired
    private ResourceDao resourceDao;

    @Override
    @Transactional
    public void initUserRoleAuthorityResource (boolean initial)
    {
        logger.debug ("initial flag: " + initial);
        if (initial)
        {
            // add 6 resources
            List <Resource> resources = new ArrayList <Resource> ();
            Resource resource = new Resource ("admin");
            resource.setValue ("/admin.do");
            if (null == resourceDao.findByName ("admin"))
            {
                resources.add (resource);
            }
            resource = new Resource ("index");
            resource.setValue ("/index.do");
            if (null == resourceDao.findByName ("index"))
            {
                resources.add (resource);
            }
            resource = new Resource ("order");
            resource.setValue ("/order.do");
            if (null == resourceDao.findByName ("order"))
            {
                resources.add (resource);
            }
            resource = new Resource ("customer");
            resource.setValue ("/customer.do");
            if (null == resourceDao.findByName ("customer"))
            {
                resources.add (resource);
            }
            resource = new Resource ("report");
            resource.setValue ("/report.do");
            if (null == resourceDao.findByName ("report"))
            {
                resources.add (resource);
            }
            resource = new Resource ("goods");
            resource.setValue ("/goods.do");
            if (null == resourceDao.findByName ("goods"))
            {
                resources.add (resource);
            }
            resource = new Resource ("New user");
            resource.setValue ("/user/newUser.html");
            if (null == resourceDao.findByName ("New user"))
            {
                resources.add (resource);
            }
            resource = new Resource ("Edit user");
            resource.setValue ("/user/updateUser.html");
            if (null == resourceDao.findByName ("Edit user"))
            {
                resources.add (resource);
            }
            resource = new Resource ("reportGoodsByPrice");
            resource.setValue ("/goodsReport/reportGoodsByPrice.html");
            if (null == resourceDao.findByName ("reportGoodsByPrice"))
            {
                resources.add (resource);
            }
            resources = (List <Resource>) resourceDao.save (resources);
            // add 6 resources end

            // add admin authority which have all resources (include 6)
            Authority authority = new Authority ("adminAuthority", resources);
            authority.setSystem (true);
            if (null == authorityDao.findByName ("adminAuthority"))
            {
                authorityDao.save (authority);
            }

            // add user authority which have 5 resources, except admin resource
            resources = new ArrayList <Resource> ();
            resources.add (resourceDao.findByName ("index"));
            resources.add (resourceDao.findByName ("customer"));
            resources.add (resourceDao.findByName ("goods"));
            resources.add (resourceDao.findByName ("order"));
            resources.add (resourceDao.findByName ("report"));
            authority = new Authority ("userAuthority", resources);
            if (null == authorityDao.findByName ("userAuthority"))
            {
                authorityDao.save (authority);
            }
            resources = new ArrayList <Resource> ();

            // add viewer authority which have only right view index jsp
            resources.add (resourceDao.findByName ("index"));
            authority = new Authority ("viewerAuthority", resources);
            if (null == authorityDao.findByName ("viewerAuthority"))
            {
                authorityDao.save (authority);
            }

            List <Role> roles = new ArrayList <Role> ();
            // set admin authority to boss role
            List <Authority> authorities = new ArrayList <Authority> ();
            authorities.add (authorityDao.findByName ("adminAuthority"));
            Role role = new Role ("boss", authorities);
            if (null == roleDao.findByName ("boss"))
            {
                roles.add (role);
            }
            // role = new Role ("admin");
            role = new Role ("ROLE_ADMIN");
            if (null == roleDao.findByName ("ROLE_ADMIN"))
            {
                roles.add (role);
            }

            // set user authority to salesman role
            authorities = new ArrayList <Authority> ();
            authorities.add (authorityDao.findByName ("userAuthority"));
            role = new Role ("ROLE_USER", authorities);
            if (null == roleDao.findByName ("ROLE_USER"))
            {
                roles.add (role);
            }
            role = new Role ("support");
            if (null == roleDao.findByName ("support"))
            {
                roles.add (role);
            }

            // set viewer authority to viewer role
            authorities = new ArrayList <Authority> ();
            authorities.add (authorityDao.findByName ("viewerAuthority"));
            role = new Role ("viewer", authorities);
            if (null == roleDao.findByName ("viewer"))
            {
                roles.add (role);
            }
            roles = (List <Role>) roleDao.save (roles);

            List <User> users = new ArrayList <User> ();
            // set boss role to boss
            roles = new ArrayList <Role> ();
            roles.add (roleDao.findByName ("boss"));
            User user = new User ("boss", "boss", roles);
            if (null == userDao.findByUserId ("boss"))
            {
                users.add (user);
            }

            // set admin role to admin
            roles = new ArrayList <Role> ();
            roles.add (roleDao.findByName ("ROLE_ADMIN"));
            roles.add (roleDao.findByName ("ROLE_USER"));
            user = new User ("admin", "admin", roles);
            if (null == userDao.findByUserId ("admin"))
            {
                users.add (user);
            }

            // set user role to user
            roles = new ArrayList <Role> ();
            roles.add (roleDao.findByName ("ROLE_USER"));
            user = new User ("salesman", "salesman", roles);
            if (null == userDao.findByUserId ("salesman"))
            {
                users.add (user);
            }

            // set support role to support
            roles = new ArrayList <Role> ();
            roles.add (roleDao.findByName ("support"));
            user = new User ("support", "support", roles);
            if (null == userDao.findByUserId ("support"))
            {
                users.add (user);
            }

            // set viewer role to viewer
            roles = new ArrayList <Role> ();
            roles.add (roleDao.findByName ("viewer"));
            user = new User ("viewer", "viewer", roles);
            if (null == userDao.findByUserId ("viewer"))
            {
                users.add (user);
            }
            users = (List <User>) userDao.save (users);
        }
    }
}
